package com.esunny.mina;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Iterator;

import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

public class MinaServer extends IoHandlerAdapter {

    private int port = 8002;

    public void start() throws IOException {
        IoAcceptor acceptor = new NioSocketAcceptor();

        acceptor.getFilterChain().addLast("logger", new LoggingFilter());

        acceptor.getFilterChain().addLast("codec",
                                          new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));

        acceptor.setHandler(this);

        acceptor.getSessionConfig().setReadBufferSize(2048);
        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 3);
        acceptor.bind(new InetSocketAddress(port));
        System.out.println(this.getClass().getCanonicalName() + "start listening port " + this.port);

    }

    @Override
    public void sessionOpened(IoSession session) {
        InetSocketAddress remoteAddress = (InetSocketAddress) session.getRemoteAddress();
        String clientIp = remoteAddress.getAddress().getHostAddress() + ":" + remoteAddress.getPort();

        System.out.println(clientIp + " connected");

    }

    @Override
    public void messageReceived(IoSession session, Object message) {

        System.out.println("message received in " + this.getClass().getCanonicalName() + " ..");

        String expression = message.toString();

        //Initialization init = Initialization.getInstance();

        HashMap<String, IoSession> clientMap = null;

        if (clientMap == null || clientMap.size() == 0) {

            session.write("error");

        } else {

            IoSession longConnSession = null;

            Iterator<String> iterator = clientMap.keySet().iterator();

            String key = "";

            while (iterator.hasNext()) {

                key = iterator.next();

                longConnSession = clientMap.get(key);

            }

            // logger.info("ShortConnect Server Session ID :" + String.valueOf(session.getId()));

            // logger.info("LongConnect Server Session ID :" + String.valueOf(longConnSession.getId()));
            longConnSession.setAttribute("shortConnSession", session);

            longConnSession.write(expression);

        }

    }

    @Override
    public void sessionIdle(IoSession session, IdleStatus status) {

        System.out.println("disconnecting in idle.");
        // disconnect an idle client

        session.close(true);

    }

    @Override
    public void exceptionCaught(IoSession session, Throwable cause) {

        // close the connection onexceptional situation

        cause.printStackTrace();

        session.close(true);

    }
}
